#ifndef STRFUNCS_H_
#define STRFUNCS_H_

#include <glibmm.h>
#include <boost/date_time/posix_time/posix_time.hpp>

#ifdef __APPLE__
typedef unsigned int uint;
#endif

namespace gpyp {

class format_rt {
private:
  gchar *data_;
  uint  *refcnt_;

  inline void destroy() {
    g_free(data_);
    delete refcnt_;
  }

  const format_rt &operator=(const format_rt &rt);

public:
  inline operator const char *() const {
    return data_;
  }
  inline operator std::string() const {
    return data_;
  }
  inline operator Glib::ustring() const {
    return data_;
  }

  const char *c_str() const {
    return data_;
  }

  inline format_rt(gchar *data) :
    data_  (data),
    refcnt_(new uint(1))
  {
  }
  inline format_rt(const format_rt &rt) :
    data_  (rt.data_),
    refcnt_(rt.refcnt_)
  {
    ++*refcnt_;
  }
  inline ~format_rt() {
    --*refcnt_;
    if (*refcnt_ == 0) destroy();
  }
};
inline std::ostream &operator<<(std::ostream &os, const format_rt &rt) {
  return os << rt.c_str();
}

inline format_rt format(const gchar *fmt, ...) {
  va_list args;
  gchar  *res;
  va_start(args, fmt);
  res = g_strdup_vprintf(fmt, args);
  va_end(args);
  return res;
}

template<typename T>
std::string tostr(const T &d) {
  std::stringstream ss;
  ss << d;
  return ss.str();
}
template<>
inline std::string tostr(const bool &b) {
  return b ? "true" : "false";
}
template<>
inline std::string tostr(const boost::posix_time::ptime &t) {
  if (t.date() == boost::gregorian::day_clock::local_day()) {
    return boost::posix_time::to_simple_string(t.time_of_day());
  } else {
    return boost::posix_time::to_simple_string(t);
  }
}
template<>
inline std::string tostr(const boost::posix_time::time_duration &td) {
  return boost::posix_time::to_simple_string(td);
}

inline int toint(const char *str, int def) {
  char *end = NULL;
  long res = strtol(str, &end, 10);
  return (end && *end == '\0') ? res : def;
}
inline uint touint(const char *str, uint def) {
  char *end = NULL;
  long long res = strtoll(str, &end, 10);
  return (end && *end == '\0' && res >= 0) ? res : def;
}
inline int toint(const std::string &str, int def) {
  return toint(str.c_str(), def);
}
inline uint touint(const std::string &str, uint def) {
  return touint(str.c_str(), def);
}

void decode_html(const char *start, const char *end, Glib::ustring &res);
void encode_html(const Glib::ustring &str, Glib::ustring &res);

}/* namespace gpyp */

#endif /*STRFUNCS_H_*/
